/**
 * 
 */
package com.brainstrongtech.bfs.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.brainstrongtech.bfs.dao.MenuDao;
import com.brainstrongtech.bfs.domian.Menu;
import com.brainstrongtech.bfs.exception.ServiceLogicException;
import com.brainstrongtech.bfs.service.MenuService;
import com.brainstrongtech.bfs.util.ObjectUtils;


/**
 * 
 * @Description:
 * @author: tianhua.xie
 * @Date: 2017年2月9日 下午9:53:07 
 * 
 */
@Service("menuService")
@Transactional
public class MenuServiceImpl implements MenuService {

	@Autowired
	private MenuDao menuDao;

	@Override
	public Map<String, Object> loadMenuTreeGrid() {

		Map<String, Object> menuTreeGridData = new HashMap<String, Object>();
		List<Map<String, Object>> menuTreeData = new ArrayList<Map<String, Object>>();
		Map<String, Object> treeNode = null;
		List<Menu> menuList = menuDao.loadAllMenus();
		
		
		for (Menu menu : menuList) {
			treeNode = new HashMap<String, Object>();
			treeNode.put("menuId", menu.getMenuId());
			treeNode.put("menuName", menu.getMenuName());
			treeNode.put("menuHref", menu.getMenuHref());
			treeNode.put("menuTarget", menu.getMenuTarget());
			if (menu.getParentId()!=0) {
				treeNode.put("_parentId", menu.getParentId());
			}
			treeNode.put("grade", menu.getGrade());
			treeNode.put("isLeaf", menu.getIsLeaf());
			treeNode.put("isShow", menu.getIsShow());
			menuTreeData.add(treeNode);
		}
		
		// "total":7,"rows":[]
		menuTreeGridData.put("total", menuList.size());
		menuTreeGridData.put("rows", menuTreeData);
		
		// Gson gson = new Gson();
		// System.out.println(gson.toJson(menuTreeGridData));

		return menuTreeGridData;
	}



	@Override
	public Long getNewMenuIdByParentId(Long parentId) {
		
		Long newMenuId = null;

		if (ObjectUtils.isBlank(parentId)) {
			throw new ServiceLogicException("父菜单ID不能为空");
		}

		//获取所有的子菜单的ID，若parentId为0，则是获取顶级菜单的所有ID
		List<Long> sunIdList = menuDao.selectSunMenuIds(parentId);
		/**
		 * parentId :  201
		 * startSunId -> 20101
		 * maxSunId -> 20199   
		 */
		long startSunId = parentId * 100 + 1;
		long maxSunId = parentId * 100 + 99;
		
		// 第一个菜单
		if (ObjectUtils.isBlank(sunIdList)) {
			return startSunId;
		}

		for (long i = startSunId; i <= maxSunId; i++) {
			// 找到第一个没有在使用的id
			if (!sunIdList.contains(i)) {
				newMenuId = i;
				break;
			}
		}

		if (ObjectUtils.isBlank(newMenuId)) {
			throw new ServiceLogicException("此父菜单已有99个子菜单，过多，不适合再创建子菜单");
		}

		return newMenuId;
	}

	@Override
	public Menu getMenuById(Long menuId) {
		if (ObjectUtils.isBlank(menuId)) {
			throw new ServiceLogicException("菜单ID不能为空");
		}
		return menuDao.selectById(menuId);
	}

	@Override
	public void save(Menu menu) {
		if (ObjectUtils.isBlank(menu)) {
			throw new ServiceLogicException("菜单信息不能为空");
		}

		// 新增的菜单一定为叶子节点
		menu.setIsLeaf(1);
		if (ObjectUtils.isBlank(menu.getParentId())) {
			menu.setParentId(0L);
			menu.setGrade(1);
		} else {
			Menu parentMenu = menuDao.selectById(menu.getParentId());
			if (ObjectUtils.isBlank(parentMenu)) {
				throw new ServiceLogicException("父菜单不存在");
			}
			menu.setGrade(parentMenu.getGrade() + 1);
			// 更新父菜单的是否叶子属性
			parentMenu.setIsLeaf(0);
			menuDao.update(parentMenu);
		}

		try {
			menuDao.insert(menu);
		} catch (Exception e) {
			throw new ServiceLogicException("该菜单名已存在");
		}
	}

	@Override
	public void modifyMenuSomeInfo(Menu menu) {
		// System.out.println(menu);

		// Menu [menuId=9, menuName=32, menuHref=123, menuTarget=bottomFrame,
		// parentId=0, grade=1, isLeaf=null, isShow=null]
		
		if (ObjectUtils.isBlank(menu)) {
			throw new ServiceLogicException("菜单信息不能为空");
		}

		Menu dbMenu = menuDao.selectById(menu.getMenuId());

		if (ObjectUtils.isBlank(dbMenu)) {
			throw new ServiceLogicException("该ID对应的菜单不存在");
		}

		dbMenu.setMenuName(menu.getMenuName());
		dbMenu.setMenuHref(menu.getMenuHref());
		dbMenu.setMenuTarget(menu.getMenuTarget());

		try {
			menuDao.update(dbMenu);
		} catch (Exception e) {
			throw new ServiceLogicException(e.getMessage());
		}

	}

	@Override
	public void delectMenuById(Long delMenuId) {

		// 检核是否为空
		if (ObjectUtils.isBlank(delMenuId)) {
			throw new ServiceLogicException("要删除的菜单ID不能为空");
		}
		// 检核是否存在
		Menu delMenu = menuDao.selectById(delMenuId);
		if (ObjectUtils.isBlank(delMenu)) {
			throw new ServiceLogicException("要删除的菜单不存在");
		}

		/**
		 * 查找delMenuId该ID的所有子菜单，查询条件不可用 menuID like '101%'，
		 * 因为一旦同一父菜单下的同一等级子菜单个数过多，如1011也会被选中，
		 * 
		 */

		// 存放所有要删除的菜单ID
		List<Long> menuIdList = new ArrayList<Long>();
		List<Menu> totalMenuList = new ArrayList<Menu>();

		// 存放所有要查询子菜单的ID
		List<Menu> selectingMenuList = new ArrayList<Menu>();
		selectingMenuList.add(delMenu);

		// 查找出该菜单ID（delMenuId）的所有子菜单ID
		while (selectingMenuList.size() > 0) {
			Menu delMenuTemp = selectingMenuList.get(0);
			selectingMenuList.remove(0);

			// 将要删除的菜单的信息先保存起来保存下来
			menuIdList.add(delMenuTemp.getMenuId());
			totalMenuList.add(delMenuTemp);

			if (delMenuTemp.getIsLeaf() == 0) {// 不是叶子节点，故有子菜单
				// 查找出所有的子菜单，并加入到待查询列表中
				selectingMenuList.addAll(menuDao.selectSunMenus(delMenuTemp.getMenuId()));
			}

		}
		// [1, 101, 10101, 1010101, 1010102, 101010101, 10101010101,
		// 1010101010101, 101010101010101]
		// System.out.println(menuIdList);

		// 判断是否有菜单正在使用（查找出所有正在使用的菜单）
		if (ObjectUtils.isNotBlank(menuDao.selectUsingMenusId(menuIdList))) {// 若有，则抛出错误提示
			StringBuffer prompt = new StringBuffer("菜单（");
			for (Menu menu : totalMenuList) {
				prompt.append(menu.getMenuName()).append("，");
			}
			prompt.deleteCharAt(prompt.length() - 1).append("）正在使用中。");
			throw new ServiceLogicException(prompt.toString());

		} else {// 若无，则删除所有
			try {
				menuDao.deleteMenusByIds(menuIdList);
			} catch (Exception e) {
				e.printStackTrace();
				throw new ServiceLogicException("系统错误", e);
			}
		}
		
		// 删除菜单及其子菜单成功后，应该判断一下，菜单delMenu的父菜单是否还有子菜单，
		// 若无子菜单，则更改为叶子节点
		List<Long> sunMenuIdList = menuDao.selectSunMenuIds(delMenu.getParentId());
		if (ObjectUtils.isBlank(sunMenuIdList)) {
			Menu parentMenu = menuDao.selectById(delMenu.getParentId());
			parentMenu.setIsLeaf(1);
			menuDao.update(parentMenu);
		}
	}
	
	


}
